home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / BufferedWriter.java < prev    next >
Text File  |  1998-09-22  |  7KB  |  241 lines

  1. /*
  2.  * @(#)BufferedWriter.java    1.13 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.io;
  16.  
  17.  
  18. /**
  19.  * Write text to a character-output stream, buffering characters so as to
  20.  * provide for the efficient writing of single characters, arrays, and strings.
  21.  *
  22.  * <p> The buffer size may be specified, or the default size may be accepted.
  23.  * The default is large enough for most purposes.
  24.  *
  25.  * <p> A newLine() method is provided, which uses the platform's own notion of
  26.  * line separator as defined by the system property <tt>line.separator</tt>.
  27.  * Not all platforms use the newline character ('\n') to terminate lines.
  28.  * Calling this method to terminate each output line is therefore preferred to
  29.  * writing a newline character directly.
  30.  *
  31.  * <p> In general, a Writer sends its output immediately to the underlying
  32.  * character or byte stream.  Unless prompt output is required, it is advisable
  33.  * to wrap a BufferedWriter around any Writer whose write() operations may be
  34.  * costly, such as FileWriters and OutputStreamWriters.  For example,
  35.  *
  36.  * <pre>
  37.  * PrintWriter out
  38.  *   = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
  39.  * </pre>
  40.  *
  41.  * will buffer the PrintWriter's output to the file.  Without buffering, each
  42.  * invocation of a print() method would cause characters to be converted into
  43.  * bytes that would then be written immediately to the file, which can be very
  44.  * inefficient.
  45.  *
  46.  * @see PrintWriter
  47.  * @see FileWriter
  48.  * @see OutputStreamWriter
  49.  *
  50.  * @version     1.13, 98/07/01
  51.  * @author    Mark Reinhold
  52.  * @since    JDK1.1
  53.  */
  54.  
  55. public class BufferedWriter extends Writer {
  56.  
  57.     private Writer out;
  58.  
  59.     private char cb[];
  60.     private int nChars, nextChar;
  61.  
  62.     private static int defaultCharBufferSize = 8192;
  63.  
  64.     /**
  65.      * Line separator string.  This is the value of the line.separator
  66.      * property at the moment that the stream was created.
  67.      */
  68.     private String lineSeparator;
  69.  
  70.     /**
  71.      * Create a buffered character-output stream that uses a default-sized
  72.      * output buffer.
  73.      *
  74.      * @param  out  A Writer
  75.      */
  76.     public BufferedWriter(Writer out) {
  77.     this(out, defaultCharBufferSize);
  78.     }
  79.  
  80.     /**
  81.      * Create a new buffered character-output stream that uses an output
  82.      * buffer of the given size.
  83.      *
  84.      * @param  out  A Writer
  85.      * @param  sz   Output-buffer size, a positive integer
  86.      *
  87.      * @exception  IllegalArgumentException  If sz is <= 0
  88.      */
  89.     public BufferedWriter(Writer out, int sz) {
  90.     super(out);
  91.     if (sz <= 0)
  92.         throw new IllegalArgumentException("Buffer size <= 0");
  93.     this.out = out;
  94.     cb = new char[sz];
  95.     nChars = sz;
  96.     nextChar = 0;
  97.     lineSeparator = System.getProperty("line.separator");
  98.     }
  99.  
  100.     /** Check to make sure that the stream has not been closed */
  101.     private void ensureOpen() throws IOException {
  102.     if (out == null)
  103.         throw new IOException("Stream closed");
  104.     }
  105.  
  106.     /**
  107.      * Flush the output buffer to the underlying character stream, without
  108.      * flushing the stream itself.  This method is non-private only so that it
  109.      * may be invoked by PrintStream.
  110.      */
  111.     void flushBuffer() throws IOException {
  112.     synchronized (lock) {
  113.         ensureOpen();
  114.         if (nextChar == 0)
  115.         return;
  116.         out.write(cb, 0, nextChar);
  117.         nextChar = 0;
  118.     }
  119.     }
  120.  
  121.     /**
  122.      * Write a single character.
  123.      *
  124.      * @exception  IOException  If an I/O error occurs
  125.      */
  126.     public void write(int c) throws IOException {
  127.     synchronized (lock) {
  128.         ensureOpen();
  129.         if (nextChar >= nChars)
  130.         flushBuffer();
  131.         cb[nextChar++] = (char) c;
  132.     }
  133.     }
  134.  
  135.     /**
  136.      * Write a portion of an array of characters.
  137.      *
  138.      * <p> Ordinarily this method stores characters from the given array into
  139.      * this stream's buffer, flushing the buffer to the underlying stream as
  140.      * needed.  If the requested length is at least as large as the buffer,
  141.      * however, then this method will flush the buffer and write the characters
  142.      * directly to the underlying stream.  Thus redundant
  143.      * <code>BufferedWriter</code>s will not copy data unnecessarily.
  144.      *
  145.      * @param  cbuf  A character array
  146.      * @param  off   Offset from which to start reading characters
  147.      * @param  len   Number of characters to write
  148.      *
  149.      * @exception  IOException  If an I/O error occurs
  150.      */
  151.     public void write(char cbuf[], int off, int len) throws IOException {
  152.     synchronized (lock) {
  153.         ensureOpen();
  154.  
  155.         if (len >= nChars) {
  156.         /* If the request length exceeds the size of the output buffer,
  157.            flush the buffer and then write the data directly.  In this
  158.            way buffered streams will cascade harmlessly. */
  159.         flushBuffer();
  160.         out.write(cbuf, off, len);
  161.         return;
  162.         }
  163.  
  164.         int b = off, t = off + len;
  165.         while (b < t) {
  166.         int d = Math.min(nChars - nextChar, t - b);
  167.         System.arraycopy(cbuf, b, cb, nextChar, d);
  168.         b += d;
  169.         nextChar += d;
  170.         if (nextChar >= nChars)
  171.             flushBuffer();
  172.         }
  173.     }
  174.     }
  175.  
  176.     /**
  177.      * Write a portion of a String.
  178.      *
  179.      * @param  s     String to be written
  180.      * @param  off   Offset from which to start reading characters
  181.      * @param  len   Number of characters to be written
  182.      *
  183.      * @exception  IOException  If an I/O error occurs
  184.      */
  185.     public void write(String s, int off, int len) throws IOException {
  186.     synchronized (lock) {
  187.         ensureOpen();
  188.  
  189.         int b = off, t = off + len;
  190.         while (b < t) {
  191.         int d = Math.min(nChars - nextChar, t - b);
  192.         s.getChars(b, b + d, cb, nextChar);
  193.         b += d;
  194.         nextChar += d;
  195.         if (nextChar >= nChars)
  196.             flushBuffer();
  197.         }
  198.     }
  199.     }
  200.  
  201.     /**
  202.      * Write a line separator.  The line separator string is defined by the
  203.      * system property <tt>line.separator</tt>, and is not necessarily a single
  204.      * newline ('\n') character.
  205.      *
  206.      * @exception  IOException  If an I/O error occurs
  207.      */
  208.     public void newLine() throws IOException {
  209.     write(lineSeparator);
  210.     }
  211.  
  212.     /**
  213.      * Flush the stream.
  214.      *
  215.      * @exception  IOException  If an I/O error occurs
  216.      */
  217.     public void flush() throws IOException {
  218.     synchronized (lock) {
  219.         flushBuffer();
  220.         out.flush();
  221.     }
  222.     }
  223.  
  224.     /**
  225.      * Close the stream.
  226.      *
  227.      * @exception  IOException  If an I/O error occurs
  228.      */
  229.     public void close() throws IOException {
  230.     synchronized (lock) {
  231.         if (out == null)
  232.         return;
  233.         flushBuffer();
  234.         out.close();
  235.         out = null;
  236.         cb = null;
  237.     }
  238.     }
  239.  
  240. }
  241.